#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
超参数调优启动脚本
Hyperparameter Tuning Launcher Script

Author: ML Team
Date: 2025-11-16
Description: 简化的超参数调优启动器
"""

import os
import sys
import subprocess
import time
from datetime import datetime


def print_banner():
    """打印横幅"""
    print("="*80)
    print("           机器学习超参数调优工具箱")
    print("        Machine Learning Hyperparameter Tuning Toolbox")
    print("="*80)
    print("支持的模型:")
    print("  - Lasso回归  - 线性模型，L1正则化")
    print("  - XGBoost    - 梯度提升树")
    print("  - LightGBM   - 轻量级梯度提升")
    print("  - 多模型融合 - 并行调优所有模型")
    print("="*80)


def check_environment():
    """检查环境"""
    print("检查环境...")

    # 检查Python版本
    if sys.version_info < (3, 7):
        print("[ERROR] 需要Python 3.7或更高版本")
        return False
    else:
        print(f"[OK] Python版本: {sys.version}")

    # 检查必要的包
    required_packages = [
        ('numpy', 'numpy'),
        ('pandas', 'pandas'),
        ('sklearn', 'scikit-learn'),
        ('xgboost', 'xgboost'),
        ('lightgbm', 'lightgbm'),
        ('joblib', 'joblib')
    ]

    missing_packages = []
    for import_name, display_name in required_packages:
        try:
            __import__(import_name)
            print(f"[OK] {display_name}")
        except ImportError:
            missing_packages.append(display_name)
            print(f"[ERROR] {display_name} 未安装")

    if missing_packages:
        print(f"\n缺少必要包: {', '.join(missing_packages)}")
        print("请运行: pip install " + " ".join(missing_packages))
        return False

    # 检查数据文件
    data_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "..", "feature")
    train_file = os.path.join(data_dir, "train_feature.csv")
    if not os.path.exists(data_dir):
        print(f"[ERROR] 数据目录不存在: {data_dir}")
        return False
    elif not os.path.exists(train_file):
        print(f"[ERROR] 训练数据文件不存在: {train_file}")
        return False

    print(f"[OK] 数据目录: {data_dir}")
    print(f"[OK] 训练数据文件: {train_file}")
    print("[OK] 环境检查完成\n")
    return True


def run_script(script_name, description):
    """运行脚本"""
    print(f"\n{'='*60}")
    print(f"运行 {description}")
    print(f"{'='*60}")

    script_path = os.path.join(os.path.dirname(__file__), script_name)

    if not os.path.exists(script_path):
        print(f"[ERROR] 脚本不存在: {script_path}")
        return False

    try:
        start_time = time.time()
        print(f"启动脚本: {script_name}")
        print(f"开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

        # 运行脚本
        result = subprocess.run(
            [sys.executable, script_path],
            cwd=os.path.dirname(__file__),
            capture_output=False,
            text=True
        )

        end_time = time.time()
        duration = end_time - start_time

        if result.returncode == 0:
            print(f"\n[SUCCESS] {description} 完成!")
            print(f"执行时间: {duration:.2f}秒")
            print(f"结束时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            return True
        else:
            print(f"\n[ERROR] {description} 失败!")
            print(f"返回码: {result.returncode}")
            print(f"执行时间: {duration:.2f}秒")
            return False

    except KeyboardInterrupt:
        print(f"\n[WARNING] {description} 被用户中断")
        return False
    except Exception as e:
        print(f"\n[ERROR] 运行 {description} 时出错: {e}")
        return False


def main():
    """主函数"""
    print_banner()

    # 检查环境
    if not check_environment():
        input("\n按回车键退出...")
        return

    while True:
        print("\n" + "="*60)
        print("请选择要调优的模型:")
        print("="*60)
        print("1. Lasso回归调优")
        print("2. XGBoost调优")
        print("3. LightGBM调优")
        print("4. 多模型并行调优 (异步)")
        print("5. 顺序调优所有模型")
        print("6. 查看调优结果")
        print("0. 退出")
        print("="*60)

        try:
            choice = input("\n请选择 (0-6): ").strip()

            if choice == "0":
                print("\n退出超参数调优工具")
                break
            elif choice == "1":
                run_script("tune_lasso.py", "Lasso回归超参数调优")
            elif choice == "2":
                run_script("tune_xgboost.py", "XGBoost超参数调优")
            elif choice == "3":
                run_script("tune_lightgbm.py", "LightGBM超参数调优")
            elif choice == "4":
                run_script("hyperparameter_tuning.py", "多模型异步并行调优")
            elif choice == "5":
                print("\n开始顺序调优所有模型...")
                models = [
                    ("tune_lasso.py", "Lasso回归调优"),
                    ("tune_xgboost.py", "XGBoost调优"),
                    ("tune_lightgbm.py", "LightGBM调优")
                ]

                all_success = True
                for script, desc in models:
                    success = run_script(script, desc)
                    if not success:
                        all_success = False
                        print(f"[WARNING] {desc} 失败，但继续执行下一个模型")
                    else:
                        print(f"[SUCCESS] {desc} 完成")

                if all_success:
                    print("\n[SUCCESS] 所有模型调优完成!")
                else:
                    print("\n[WARNING] 部分模型调优失败")

            elif choice == "6":
                show_tuning_results()
            else:
                print("[ERROR] 无效选择，请输入0-6")

        except KeyboardInterrupt:
            print("\n\n程序被用户中断")
            break
        except Exception as e:
            print(f"\n❌ 发生错误: {e}")

        input("\n按回车键继续...")


def show_tuning_results():
    """显示调优结果"""
    print("\n" + "="*60)
    print("调优结果汇总")
    print("="*60)

    model_dirs = [
        ("lasso_tuning", "Lasso回归"),
        ("xgboost_tuning", "XGBoost"),
        ("lightgbm_tuning", "LightGBM")
    ]

    base_dir = os.path.dirname(__file__)
    found_results = False

    for dir_name, model_name in model_dirs:
        dir_path = os.path.join(base_dir, dir_name)
        if os.path.exists(dir_path):
            print(f"\n{model_name}调优结果:")
            print("-" * 40)

            # 查找JSON结果文件
            json_files = [f for f in os.listdir(dir_path) if f.endswith('.json')]
            if json_files:
                # 按时间排序，取最新的
                json_files.sort(reverse=True)
                latest_file = json_files[0]

                try:
                    import json
                    with open(os.path.join(dir_path, latest_file), 'r', encoding='utf-8') as f:
                        data = json.load(f)

                    if 'analysis' in data:
                        analysis = data['analysis']
                        print(f"  最佳RMSE: {analysis['best_rmse']:.6f}")
                        print(f"  R²:       {analysis['best_r2']:.4f}")
                        print(f"  搜索类型: {analysis['search_type']}")
                        print(f"  成功率:   {analysis['successful_evaluations']/analysis['total_evaluations']*100:.1f}%")
                        print(f"  结果文件: {latest_file}")
                        found_results = True

                except Exception as e:
                    print(f"  读取结果文件失败: {e}")
            else:
                print("  未找到结果文件")
        else:
            print(f"\n{model_name}: 未找到调优结果目录")

    if not found_results:
        print("\n[WARNING] 未找到任何调优结果")
        print("请先运行调优脚本")
    else:
        print(f"\n[INFO] 所有结果保存在对应的tuning目录中")
        print("[INFO] 详细信息请查看JSON和CSV结果文件")


if __name__ == "__main__":
    main()